package me.wangcai.trafficpoliceai.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import me.wangcai.trafficpoliceai.config.component.JwtTokenUtils;
import me.wangcai.trafficpoliceai.config.component.VerCodeGenerateUtil;
import me.wangcai.trafficpoliceai.model.ResponseInfo;
import me.wangcai.trafficpoliceai.model.entity.DriverInfo;
import me.wangcai.trafficpoliceai.model.entity.MailCode;
import me.wangcai.trafficpoliceai.model.entity.User;
import me.wangcai.trafficpoliceai.model.request.*;
import me.wangcai.trafficpoliceai.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.*;

@RestController
@CrossOrigin
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserService userService;
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private JwtTokenUtils jwtTokenUtils;
    @Autowired
    private JavaMailSender mailSender;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Value("${spring.mail.username}")
    private String from;

    private HashMap<String,MailCode> mailCodeMap = new HashMap<>();

    @PostMapping("/login")
    public ResponseInfo loginRequest(@RequestBody LoginRequest loginRequest, HttpServletRequest request){
        String captcha = (String) request.getSession().getAttribute("captcha");
        if (loginRequest.getCode().equals("") || !loginRequest.getCode().equalsIgnoreCase(captcha)) {
            return ResponseInfo.error("验证码填写错误！");
        }
        UserDetails userDetails = userDetailsService.loadUserByUsername(loginRequest.getUsername());
        if (null == userDetails || !passwordEncoder.matches(loginRequest.getPassword(),
                userDetails.getPassword())) {
            return ResponseInfo.error("用户名或密码不正确!");
        }
        UsernamePasswordAuthenticationToken authentication =
                new UsernamePasswordAuthenticationToken(userDetails, null,
                        userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
        String token = jwtTokenUtils.generateToken(userDetails);
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);
        return ResponseInfo.success("登录成功", tokenMap);
    }


    @PostMapping( "/register")
    public ResponseInfo register(@RequestBody RegisterRequest registerRequest) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String encoderPassword = encoder.encode(registerRequest.getPassword());
        registerRequest.setPassword(encoderPassword);
        MailCode mailCode = mailCodeMap.get(registerRequest.getEmail());
        mailCodeMap.remove(registerRequest.getEmail());
        if(mailCode == null){
            return ResponseInfo.error("未发送验证码!");
        }
        if(System.currentTimeMillis() - mailCode.getTime() > 60 * 5 * 1000){
            return ResponseInfo.error("验证码超时!");
        }
        if(!mailCode.getCode().equalsIgnoreCase(registerRequest.getCode())){
            return ResponseInfo.error("验证码错误!");
        }
        User user = new User(registerRequest.getUsername(),encoderPassword,registerRequest.getEmail());
        if(userService.register(user)){
            return ResponseInfo.success("注册成功!");
        }else{
            return ResponseInfo.error("注册失败,邮箱或用户名已被注册!");
        }

    }

    @PostMapping("/AppletLogin")
    public ResponseInfo appletLogin(@RequestBody AppletLoginRequest appletLoginRequest){
        User user = userService.getUserByName(appletLoginRequest.getUsername());
        UserDetails userDetails;
        boolean reg = false;
        if(null == user){
            user = new User();
            reg = true;
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            String encoderPassword = encoder.encode(appletLoginRequest.getPassword());
            user.setUsername(appletLoginRequest.getUsername());
            user.setPassword(encoderPassword);
            user.setCarId( appletLoginRequest.getCarId());
            userService.save(user);
        }else{
            userDetails = userDetailsService.loadUserByUsername(appletLoginRequest.getUsername());
            if (!passwordEncoder.matches(appletLoginRequest.getPassword(),
                    userDetails.getPassword())) {
                return ResponseInfo.error("用户名或密码不正确!");
            }
        }
        userDetails = userDetailsService.loadUserByUsername(appletLoginRequest.getUsername());
        UsernamePasswordAuthenticationToken authentication =
                new UsernamePasswordAuthenticationToken(userDetails, null,
                        userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
        String token = jwtTokenUtils.generateToken(userDetails);
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);
        return ResponseInfo.success(reg ? "自动为你完成注册!" : "登录成功!", tokenMap);
    }


    @PostMapping("/getUserInfo")
    public ResponseInfo getUserInfo(Principal principal) {
        return ResponseInfo.success("查询成功",userService.getUserByName(principal.getName()));
    }

    //管理员获取用户列表
    @PostMapping("/getUserList")
    public ResponseInfo getUserList(Principal principal,@RequestBody PageRequest pageRequest) {
        return userService.getUserList(pageRequest.getPage(),pageRequest.getAmount());
    }

    //编辑用户
    @PostMapping("/editUser")
    public ResponseInfo editUser(Principal principal,@RequestBody EditUserRequest editUserRequest) {
        User user = userService.getUserByName(principal.getName());
        User editUser = userService.getUserById(editUserRequest.getId());
        if(editUser.getPermission().getIndex() >= user.getPermission().getIndex()){
            return ResponseInfo.error("你没有足够的权限修改!");
        }
        if(!userService.editUser(editUserRequest.getId(),editUserRequest.getPassword(),editUserRequest.getCarId(),editUserRequest.getMail(),editUserRequest.getPermission())){
            return ResponseInfo.error("修改失败");
        }
        return ResponseInfo.success("修改成功!");
    }

    @PostMapping("/register/sendEmail")
    public ResponseInfo commonEmail(@RequestBody MailRequest mailRequest) {
//        创建邮件消息
        SimpleMailMessage message = new SimpleMailMessage();

        message.setFrom(from);

        message.setTo(mailRequest.getMail());

        message.setSubject("您本次的验证码是");

        String verCode = VerCodeGenerateUtil.generateVerCode();

        mailCodeMap.put(mailRequest.getMail(),new MailCode(verCode,System.currentTimeMillis()));

        message.setText("尊敬的用户,您好:\n"
                + "\n本次请求的邮件验证码为:" + verCode + ",本验证码 5 分钟内效，请及时输入。（请勿泄露此验证码）\n"
                + "\n如非本人操作，请忽略该邮件。\n(这是一封通过自动发送的邮件，请不要直接回复）");

        mailSender.send(message);
        return ResponseInfo.success("发送成功");
    }

    @PostMapping("/filter")
    public ResponseInfo filterUser(@RequestBody HashMap<String,String> map){
        return userService.filterUser(map);
    }

    @PostMapping("/driverinfo")
    public ResponseInfo getDriverInfo(){
        return ResponseInfo.success("获取成功",new DriverInfo());
    }

    @PostMapping("/driverInfoList")
    public ResponseInfo getDriverInfoList(@RequestBody DriverInfoListRequest driverInfoListRequest){
        List<DriverInfo> driverInfoList = new ArrayList<>();
        DriverInfo info = new DriverInfo();
        if(driverInfoListRequest.getName() != null){
            for (int i = 0; i < new Random().nextInt(10) + 10; i++) {
                DriverInfo driverInfo = new DriverInfo();
                driverInfo.setName(driverInfoListRequest.getName());
                driverInfoList.add(driverInfo);
            }
        }else if(driverInfoListRequest.getCarId() != null){
            info.setCarId(driverInfoListRequest.getCarId());
            driverInfoList.add(info);
        }else if(driverInfoListRequest.getPhone() != null){
            info.setPhone(driverInfoListRequest.getPhone());
            driverInfoList.add(info);
        }else{
            for (int i = 0; i < driverInfoListRequest.getAmount(); i++) {
                driverInfoList.add(new DriverInfo());
            }
        }
        return ResponseInfo.success("获取成功",driverInfoList);
    }

}
